package mspbots.autotask.common;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import java.util.List;

/**
 * mspbots.data.autotask.utils.QueryBody
 * <a href="https://www.autotask.net/help/DeveloperHelp/Content/AdminSetup/2ExtensionsIntegrations/APIs/REST/API_Calls/REST_Basic_Query_Calls.htm">Making basic query calls to the Autotask PSA REST API</a>
 * <br>
 * Grouping query
 * JSON syntax
 * To use this query, replace each of the following placeholders with the values described.
 * <p>
 * GroupingOperator fields: Designate the type of search you'd like to perform by entering an operator value. When working with grouping operators, you may select AND or OR.
 * FilterExpression fields: Enter the filter expressions you'd like to send for your query, as described in the earlier sections of this article. You may include operator values from the list of filter operators.
 * <code>
 * {
 * "filter": [
 * {
 * "op": "eq",
 * "field": "IsActive",
 * "value": true
 * },
 * {
 * "op": "or",
 * "items": [
 * {
 * "op": "eq",
 * "field": "lastname",
 * "value": "Smith"
 * },
 * {
 * "op": "eq",
 * "field": "lastname",
 * "value": "Jones"
 * },
 * {
 * "op": "and",
 * "items": [
 * {
 * "op": "eq",
 * "field": "firstname",
 * "value": "Chris"
 * },
 * {
 * "op": "eq",
 * "field": "lastname",
 * "value": "Brady"
 * }
 * ]
 * }
 * ]
 * }
 * ]
 * }
 * </code>
 *
 * @author <a href="https://github.com/vnobo">Alex bob</a>
 * @date Created by 2020/7/9
 */
@Data
@NoArgsConstructor
@ApiModel("Auto task api query model")
public class QueryBody {

    @ApiModelProperty(value = "Specifying the maximum records to return. default 50", example = "50")
    private int maxRecords;

    @ApiModelProperty(value = "Specifying fields to return. example:id,name")
    private List<String> includeFields;

    @Valid
    @NotNull(message = "Find filter expression cannot be null")
    @ApiModelProperty(value = "Filter operators, default: {\n \"filter\": [\n{\n\"op\": " +
            "\"gte\",\n\"field\": \"id\",\n \"value\": \"0\"\n}\n]\n}")
    private List<FilterExpression> filter;

    @Builder
    public QueryBody(int maxRecords, List<String> includeFields, List<FilterExpression> filter) {
        this.maxRecords = maxRecords;
        this.includeFields = includeFields;
        this.filter = filter;
    }

    /**
     * default query params
     * max records 25, id>0
     *
     * @return default query body
     */
    public static QueryBody withDefault() {
        return new QueryBody(50, null, List.of(FilterExpression.withDefault()));
    }

    /**
     * query params with FilterExpression
     * max records 500
     *
     * @param expression fiter expression
     * @return default query body
     */
    public static QueryBody withFilter(FilterExpression expression) {
        List<FilterExpression> filterExpressionList = List.of(expression);
        return withFilters(filterExpressionList);
    }

    /**
     * query params with FilterExpression
     * max records 500
     *
     * @param expression fiter expression
     * @return default query body
     */
    public static QueryBody withFilters(List<FilterExpression> expression) {
        QueryBody queryBody = withDefault();
        queryBody.setFilter(expression);
        return queryBody;
    }
}
